package cz.incad.psh.pshassign.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;


import static com.google.gwt.query.client.GQuery.$;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import static gwtquery.plugins.ui.Ui.Ui;

import java.util.Iterator;
import java.util.Set;

/**
 *
 * @author Alberto Hernandez
 */
public class Heslo extends Composite {

    private static HesloUiBinder uiBinder = GWT.create(HesloUiBinder.class);

    interface HesloUiBinder extends UiBinder<Widget, Heslo> {
    }
    
    @UiField
    Anchor link;
    @UiField
    Label score;
    @UiField
    Label help;
    @UiField
    Label path;
    @UiField
    CheckBox active;
    @UiField
    FlowPanel hlPanel;
    
    @UiField
    FlowPanel rank_explain;
    
    String label;
    boolean isExact;
    boolean isMultiple;

    private int getNumHits(String s) {
//        return count(s, "<b>") ;
        int res = 0;
        String patternStr = "<b>(.*?)<\\/b>";
        RegExp regExp = RegExp.compile(patternStr, "ig");

        for (MatchResult matcher = regExp.exec(s); matcher != null; matcher = regExp.exec(s)) {
            res++;
        }
        return res;
    }

    private int count(final String string, final String substring) {
        int count = 0;
        int idx = 0;

        while ((idx = string.indexOf(substring, idx)) != -1) {
            idx++;
            count++;
        }

        return count;
    }
    
    public String getLabel(){
        return this.label;
    }

    public void setStrength(String strength) {
        if ("multiple".equals(strength)) {
            this.setVisible(isMultiple || isExact);
        } else if ("exact".equals(strength)) {
            this.setVisible(isExact);
        } else {
            this.setVisible(true);
        }
    }

    public Heslo(JSONObject js) throws Exception {
        initWidget(uiBinder.createAndBindUi(this));
        this.isExact = js.get("isExact").isBoolean().booleanValue();
        this.isMultiple = js.get("isMultiple").isBoolean().booleanValue();

        active.setStyleName("save");
        this.label = js.get("label").isString().stringValue();
        link.setText(this.label);
        link.setHref(js.get("uri").isString().stringValue());
        link.setTarget("_blank");
        MainPage mainPage = (MainPage) RootLayoutPanel.get().getWidget(0);

        double sc = js.get("rank").isNumber().doubleValue()
                + (js.get("score").isNumber().doubleValue() * mainPage.getIntOption("assign", "boost_solr") );

        score.setText("(" + NumberFormat.getFormat("0.0").format(sc) + ")");
//        score.setTitle(js.get("rank").isNumber().toString() + " x " + 
//                js.get("score").isNumber().toString());

        String ex = "";
        JSONObject exArray = js.get("rank_explain").isObject();
        Set ks = exArray.keySet();
        for (Iterator iter = ks.iterator(); iter.hasNext();) {
            String word = (String) iter.next();
            ex += word + "<br/>";
            if (exArray.get(word).isObject() != null) {
                JSONObject jo = exArray.get(word).isObject();
                Set ks2 = jo.keySet();
                for (Iterator iter2 = ks2.iterator(); iter2.hasNext();) {
                    String f = (String) iter2.next();
                    if (!"word total".equals(f)) {
                        ex += "&nbsp;&nbsp;&nbsp;" + f + ": " + jo.get(f) + " <br/>";
                    }
                }
                ex += "&nbsp;&nbsp;&nbsp;word total: " + jo.get("word total") + " <br/>";
            } else {
                JSONArray ja = exArray.get(word).isArray();
                for (int i = 0; i < ja.size(); i++) {
                    JSONObject jo = ja.get(i).isObject();
                    Set ks2 = jo.keySet();
                    for (Iterator iter2 = ks2.iterator(); iter2.hasNext();) {
                        String f = (String) iter2.next();
                        if (!"word total".equals(f)) {
                            ex += "&nbsp;&nbsp;&nbsp;" + f + ": " + jo.get(f) + " <br/>";
                        }
                    }
                    ex += "&nbsp;&nbsp;&nbsp;word total: <b>" + jo.get("word total") + "</b><br/>";
                }

            }
        }
        

        ex += "proximity: " + 
                (mainPage.getIntOption("assign", "boost_proximity") * js.get("proximity").isNumber().doubleValue()) + 
                " (" + mainPage.getIntOption("assign", "boost_proximity") +
                " x " + js.get("proximity").isNumber().toString() + ") <br/>";
        
        ex += "level: " + 
                (mainPage.getDoubleOption("assign", "boost_level") * js.get("level").isNumber().doubleValue()) + 
                " (" + mainPage.getDoubleOption("assign", "boost_level") +
                " x " + js.get("level").isNumber().toString() + ") <br/>";
        if(isExact){
            ex += "exact: " + mainPage.getDoubleOption("assign", "boost_exact") + " <br/>";
        }
        if(isMultiple){
            ex += "multiple: " + mainPage.getDoubleOption("assign", "boost_multiple") + " <br/>";
        }
        ex += "rank: " + js.get("rank").isNumber().toString() + " <br/>";
        ex += "solr score: " + js.get("score").isNumber().toString() + " <br/>";
        ex += "total = rank + (solr score x "+mainPage.getIntOption("assign", "boost_solr")+")";
        
        help.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                $(rank_explain.getElement()).as(Ui).dialog();
            }
        });
        
        
        //rank_explain.getElement().setAttribute("id", "rank_explain");
        rank_explain.add(new HTMLPanel(ex));
        rank_explain.setTitle("Rank explain for " + label);
        rank_explain.setVisible(false);

        path.setText(js.get("path").isString().stringValue());

        JSONObject hlObject = js.get("hlObject").isObject();
        Set keys = hlObject.keySet();
        for (Iterator iter = keys.iterator(); iter.hasNext();) {
            String key = (String) iter.next();
            JSONArray hlFields = hlObject.get(key).isArray();
            for (int j = 0; j < hlFields.size(); j++) {
                hlPanel.add(new HTMLPanel(hlFields.get(j).isString().stringValue() + " in " + key));
            }
        }
    }

    public boolean shouldSave() {
        return active.getValue();
    }
}
